package com.weixing.oauth2.common.oauth2.provider.sms;

import com.weixing.oauth2.common.oauth2.provider.AbstractCustomTokenGranter;
import com.weixing.oauth2.common.userdetails.IUserDetailsService;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;

import java.util.LinkedHashMap;
import java.util.Map;


/**
 * Description:短信验证码登录令牌授予者  <br/>
 *
 * @param:
 * @return:
 * @Author: kfc
 * @Date: 2019/9/24 18:59
 */
public class SmsTokenGranter extends AbstractCustomTokenGranter {
    private static final String GRANT_TYPE = "sms";
    private IUserDetailsService userDetailsService;

    public SmsTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, IUserDetailsService userDetailsService) {
        super(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
        this.userDetailsService = userDetailsService;
    }


    @Override
    protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
        Map<String, String> parameters = new LinkedHashMap(tokenRequest.getRequestParameters());
        String mobile = (String) parameters.get("username");
        UserDetails user = userDetailsService.loadUserByMobile(mobile);
        if (null == user) {
            throw new InvalidGrantException("用户不存在");
        }
        Authentication userAuth = new UsernamePasswordAuthenticationToken(mobile, null);
        ((AbstractAuthenticationToken) userAuth).setDetails(parameters);
        userAuth.setAuthenticated(true);

        if (userAuth != null && userAuth.isAuthenticated()) {
            OAuth2Request storedOAuth2Request = this.getRequestFactory().createOAuth2Request(client, tokenRequest);
            return new OAuth2Authentication(storedOAuth2Request, userAuth);
        } else {
            throw new InvalidGrantException("Could not authenticate user: " + mobile);
        }
    }

    @Override
    protected UserDetails getUserDetails(Map<String, String> parameters) {
        String phone = parameters.get("username");
        String smsCode = parameters.get("smsCode");
        return userDetailsService.loadUserByPhoneAndSmsCode(phone, smsCode);
    }
}